package org.csu.onlineedubackend.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.csu.onlineedubackend.entity.*;
import org.csu.onlineedubackend.mapper.*;
import org.csu.onlineedubackend.service.StudentCenterService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class StudentCenterServiceImpl implements StudentCenterService {

    @Autowired
    private LessonProgressMapper lessonProgressMapper;
    
    @Autowired
    private LessonMapper lessonMapper;
    
    @Autowired
    private ChapterMapper chapterMapper;
    
    @Autowired
    private CourseMapper courseMapper;
    
    @Autowired
    private CourseSubscribeMapper courseSubscribeMapper;
    
    @Autowired
    private CourseLikeMapper courseLikeMapper;
    
    @Autowired
    private UserMapper userMapper;

    @Override
    public List<Map<String, Object>> getRecentCourses(Integer studentId, Integer limit) {
        // 1. 获取学生最近观看的课时记录
        QueryWrapper<LessonProgress> wrapper = new QueryWrapper<>();
        wrapper.eq("student_id", studentId)
               .orderByDesc("last_watch")
               .last("LIMIT " + limit);
        List<LessonProgress> progressList = lessonProgressMapper.selectList(wrapper);
        
        // 2. 如果没有观看记录，返回空列表
        if (progressList.isEmpty()) {
            return Collections.emptyList();
        }
        
        // 3. 获取对应的课程信息
        Set<Integer> courseIdSet = new HashSet<>();
        Map<Integer, LocalDateTime> courseLastWatchMap = new HashMap<>();
        
        for (LessonProgress progress : progressList) {
            // 获取课时对应的课程ID
            Lesson lesson = lessonMapper.selectById(progress.getLessonId());
            if (lesson != null) {
                Chapter chapter = chapterMapper.selectById(lesson.getChapterId());
                if (chapter != null) {
                    Integer courseId = chapter.getCourseId();
                    courseIdSet.add(courseId);
                    
                    // 记录每个课程的最后观看时间
                    if (!courseLastWatchMap.containsKey(courseId) || 
                        progress.getLastWatch().isAfter(courseLastWatchMap.get(courseId))) {
                        courseLastWatchMap.put(courseId, progress.getLastWatch());
                    }
                }
            }
        }
        
        // 4. 查询这些课程的详细信息
        List<Course> courseList = new ArrayList<>();
        for (Integer courseId : courseIdSet) {
            Course course = courseMapper.selectById(courseId);
            if (course != null) {
                courseList.add(course);
            }
        }
        
        // 5. 按最后观看时间排序
        courseList.sort((c1, c2) -> {
            LocalDateTime time1 = courseLastWatchMap.get(c1.getId());
            LocalDateTime time2 = courseLastWatchMap.get(c2.getId());
            return time2.compareTo(time1); // 降序
        });
        
        // 6. 限制返回数量
        if (courseList.size() > limit) {
            courseList = courseList.subList(0, limit);
        }
        
        // 7. 计算每个课程的进度
        List<Map<String, Object>> result = new ArrayList<>();
        for (Course course : courseList) {
            Map<String, Object> courseMap = new HashMap<>();
            courseMap.put("id", course.getId());
            courseMap.put("title", course.getTitle());
            courseMap.put("coverUrl", course.getCoverUrl());
            
            // 获取课程的总课时数
            int totalLessons = getTotalLessonsByCourseId(course.getId());
            courseMap.put("totalLessons", totalLessons);
            
            // 获取已完成课时数
            int completedLessons = getCompletedLessonsByCourseIdAndStudentId(course.getId(), studentId);
            courseMap.put("lessonsCompleted", completedLessons);
            
            // 计算进度百分比
            int progress = totalLessons > 0 ? (completedLessons * 100 / totalLessons) : 0;
            courseMap.put("progress", progress);
            
            // 计算总时长
            int duration = getTotalDurationByCourseId(course.getId());
            courseMap.put("duration", formatDuration(duration));
            
            result.add(courseMap);
        }
        
        return result;
    }

    @Override
    public Map<String, Object> getActivityData(Integer studentId, Integer days) {
        Map<String, Object> result = new HashMap<>();
        List<Map<String, Object>> activityData = new ArrayList<>();
        List<String> dateLabels = new ArrayList<>();
        List<Integer> watchDurations = new ArrayList<>();
        
        // 获取指定天数的日期标签和每日观看时长
        LocalDate endDate = LocalDate.now();
        LocalDate startDate = endDate.minusDays(days - 1);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM-dd");
        
        for (LocalDate date = startDate; !date.isAfter(endDate); date = date.plusDays(1)) {
            String dateStr = date.format(formatter);
            dateLabels.add(dateStr);
            
            // 计算该日的观看时长（分钟）
            int duration = calculateWatchDurationByDate(studentId, date);
            watchDurations.add(duration);
            
            Map<String, Object> dailyData = new HashMap<>();
            dailyData.put("date", dateStr);
            dailyData.put("duration", duration);
            activityData.add(dailyData);
        }
        
        result.put("labels", dateLabels);
        result.put("data", watchDurations);
        result.put("detailedData", activityData);
        
        return result;
    }

    @Override
    public Map<String, Object> getProgressCategoryData(Integer studentId) {
        Map<String, Object> result = new HashMap<>();
        
        // 获取当天更新的课时数目
        LocalDate today = LocalDate.now();
        int todayUpdatedLessons = countUpdatedLessonsByDate(studentId, today);
        
        // 定义进度分类标准
        String category;
        if (todayUpdatedLessons <= 2) {
            category = "light"; // 轻度学习
        } else if (todayUpdatedLessons <= 5) {
            category = "medium"; // 中度学习
        } else {
            category = "heavy"; // 重度学习
        }
        
        // 获取当月的学习日历数据
        List<Map<String, Object>> calendarData = generateMonthlyCalendarData(studentId);
        
        result.put("category", category);
        result.put("updatedLessons", todayUpdatedLessons);
        result.put("calendarData", calendarData);
        
        return result;
    }

    @Override
    public List<Map<String, Object>> getSubscribedUncompletedCourses(Integer studentId, Integer limit) {
        // 获取学生订阅的课程
        List<Integer> subscribedCourseIds = getSubscribedCourseIds(studentId);
        if (subscribedCourseIds.isEmpty()) {
            return Collections.emptyList();
        }
        
        // 查询每个课程的完成情况，筛选出未完成的课程
        List<Map<String, Object>> uncompletedCourses = new ArrayList<>();
        for (Integer courseId : subscribedCourseIds) {
            // 计算课程完成情况
            int totalLessons = getTotalLessonsByCourseId(courseId);
            int completedLessons = getCompletedLessonsByCourseIdAndStudentId(courseId, studentId);
            
            // 如果未完全完成，则添加到结果集
            if (completedLessons < totalLessons) {
                Course course = courseMapper.selectById(courseId);
                if (course != null) {
                    Map<String, Object> courseMap = new HashMap<>();
                    courseMap.put("id", course.getId());
                    courseMap.put("title", course.getTitle());
                    courseMap.put("coverUrl", course.getCoverUrl());
                    // 添加教师信息
                    courseMap.put("teacherId", course.getTeacherId());
                    try {
                        User teacher = userMapper.selectById(course.getTeacherId());
                        String teacherName = teacher != null ? teacher.getUsername() : "未知教师";
                        courseMap.put("teacherName", teacherName);
                    } catch (Exception e) {
                        courseMap.put("teacherName", "未知教师");
                    }
                    courseMap.put("totalLessons", totalLessons);
                    courseMap.put("lessonsCompleted", completedLessons);
                    
                    // 计算进度百分比
                    int progress = totalLessons > 0 ? (completedLessons * 100 / totalLessons) : 0;
                    courseMap.put("progress", progress);
                    
                    // 计算总时长
                    int duration = getTotalDurationByCourseId(courseId);
                    courseMap.put("duration", formatDuration(duration));
                    
                    uncompletedCourses.add(courseMap);
                }
            }
        }
        
        // 按进度降序排序
        uncompletedCourses.sort((c1, c2) -> {
            Integer p1 = (Integer) c1.get("progress");
            Integer p2 = (Integer) c2.get("progress");
            return p2.compareTo(p1); // 降序
        });
        
        // 限制返回数量
        if (limit > 0 && uncompletedCourses.size() > limit) {
            return uncompletedCourses.subList(0, limit);
        }
        
        return uncompletedCourses;
    }

    @Override
    public List<Map<String, Object>> getSubscribedCompletedCourses(Integer studentId, Integer limit) {
        // 获取学生订阅的课程
        List<Integer> subscribedCourseIds = getSubscribedCourseIds(studentId);
        if (subscribedCourseIds.isEmpty()) {
            return Collections.emptyList();
        }
        
        // 查询每个课程的完成情况，筛选出已完成的课程
        List<Map<String, Object>> completedCourses = new ArrayList<>();
        for (Integer courseId : subscribedCourseIds) {
            // 计算课程完成情况
            int totalLessons = getTotalLessonsByCourseId(courseId);
            int completedLessons = getCompletedLessonsByCourseIdAndStudentId(courseId, studentId);
            
            // 如果全部完成，则添加到结果集
            if (completedLessons >= totalLessons && totalLessons > 0) {
                Course course = courseMapper.selectById(courseId);
                if (course != null) {
                    Map<String, Object> courseMap = new HashMap<>();
                    courseMap.put("id", course.getId());
                    courseMap.put("title", course.getTitle());
                    courseMap.put("coverUrl", course.getCoverUrl());
                    // 添加教师信息
                    courseMap.put("teacherId", course.getTeacherId());
                    try {
                        User teacher = userMapper.selectById(course.getTeacherId());
                        String teacherName = teacher != null ? teacher.getUsername() : "未知教师";
                        courseMap.put("teacherName", teacherName);
                    } catch (Exception e) {
                        courseMap.put("teacherName", "未知教师");
                    }
                    courseMap.put("totalLessons", totalLessons);
                    courseMap.put("lessonsCompleted", completedLessons);
                    courseMap.put("progress", 100);
                    
                    // 计算总时长
                    int duration = getTotalDurationByCourseId(courseId);
                    courseMap.put("duration", formatDuration(duration));
                    
                    completedCourses.add(courseMap);
                }
            }
        }
        
        // 按完成时间降序排序（这里可能需要额外的逻辑获取完成时间）
        
        // 限制返回数量
        if (limit > 0 && completedCourses.size() > limit) {
            return completedCourses.subList(0, limit);
        }
        
        return completedCourses;
    }

    @Override
    public List<Map<String, Object>> getLikedCourses(Integer studentId) {
        // 获取学生收藏的课程
        QueryWrapper<CourseLike> wrapper = new QueryWrapper<>();
        wrapper.eq("student_id", studentId);
        List<CourseLike> likeList = courseLikeMapper.selectList(wrapper);
        
        if (likeList.isEmpty()) {
            return Collections.emptyList();
        }
        
        // 查询课程详情
        List<Map<String, Object>> likedCourses = new ArrayList<>();
        for (CourseLike like : likeList) {
            Course course = courseMapper.selectById(like.getCourseId());
            if (course != null) {
                Map<String, Object> courseMap = new HashMap<>();
                courseMap.put("id", course.getId());
                courseMap.put("title", course.getTitle());
                courseMap.put("coverUrl", course.getCoverUrl());
                courseMap.put("price", course.getPrice());
                
                // 获取教师信息
                User teacher = userMapper.selectById(course.getTeacherId());
                String teacherName = teacher != null ? teacher.getUsername() : "未知教师";
                courseMap.put("teacherName", teacherName);
                
                courseMap.put("subscriberCount", course.getSubscriberCount());
                
                // 检查是否已订阅
                boolean isSubscribed = isStudentSubscribedCourse(studentId, course.getId());
                courseMap.put("isSubscribed", isSubscribed);
                
                likedCourses.add(courseMap);
            }
        }
        
        // 按收藏时间降序排序
        likedCourses.sort((c1, c2) -> {
            Integer id1 = (Integer) c1.get("id");
            Integer id2 = (Integer) c2.get("id");
            
            // 找到对应的CourseLike对象
            CourseLike like1 = likeList.stream()
                    .filter(l -> l.getCourseId().equals(id1))
                    .findFirst().orElse(null);
            CourseLike like2 = likeList.stream()
                    .filter(l -> l.getCourseId().equals(id2))
                    .findFirst().orElse(null);
            
            if (like1 != null && like2 != null && like1.getCreatedAt() != null && like2.getCreatedAt() != null) {
                return like2.getCreatedAt().compareTo(like1.getCreatedAt()); // 降序
            }
            return 0;
        });
        
        return likedCourses;
    }

    @Override
    public List<Map<String, Object>> getAllSubscribedUncompletedCourses(Integer studentId) {
        // 获取所有订阅但未完成的课程，不限制数量
        return getSubscribedUncompletedCourses(studentId, 0);
    }
    
    // 辅助方法：获取学生订阅的课程ID列表
    private List<Integer> getSubscribedCourseIds(Integer studentId) {
        QueryWrapper<CourseSubscribe> wrapper = new QueryWrapper<>();
        wrapper.eq("student_id", studentId);
        List<CourseSubscribe> subscribeList = courseSubscribeMapper.selectList(wrapper);
        
        return subscribeList.stream()
                .map(CourseSubscribe::getCourseId)
                .collect(Collectors.toList());
    }
    
    // 辅助方法：获取课程的总课时数
    private int getTotalLessonsByCourseId(Integer courseId) {
        // 获取课程的章节列表
        QueryWrapper<Chapter> chapterWrapper = new QueryWrapper<>();
        chapterWrapper.eq("course_id", courseId);
        List<Chapter> chapters = chapterMapper.selectList(chapterWrapper);
        
        if (chapters.isEmpty()) {
            return 0;
        }
        
        // 计算总课时数
        int totalLessons = 0;
        for (Chapter chapter : chapters) {
            QueryWrapper<Lesson> lessonWrapper = new QueryWrapper<>();
            lessonWrapper.eq("chapter_id", chapter.getId());
            Long count = lessonMapper.selectCount(lessonWrapper);
            totalLessons += (count != null ? count.intValue() : 0);
        }
        
        return totalLessons;
    }
    
    // 辅助方法：获取学生已完成的课时数
    private int getCompletedLessonsByCourseIdAndStudentId(Integer courseId, Integer studentId) {
        // 获取课程的章节列表
        QueryWrapper<Chapter> chapterWrapper = new QueryWrapper<>();
        chapterWrapper.eq("course_id", courseId);
        List<Chapter> chapters = chapterMapper.selectList(chapterWrapper);
        
        if (chapters.isEmpty()) {
            return 0;
        }
        
        // 计算已完成课时数
        int completedLessons = 0;
        for (Chapter chapter : chapters) {
            // 获取章节的所有课时
            QueryWrapper<Lesson> lessonWrapper = new QueryWrapper<>();
            lessonWrapper.eq("chapter_id", chapter.getId());
            List<Lesson> lessons = lessonMapper.selectList(lessonWrapper);
            
            // 检查每个课时的完成情况
            for (Lesson lesson : lessons) {
                LessonProgress progress = lessonProgressMapper.selectByStudentAndLesson(studentId, lesson.getId());
                if (progress != null && progress.getProgress() == 100.0) { 
                    completedLessons++;
                }
            }
        }
        
        return completedLessons;
    }
    
    // 辅助方法：获取课程的总时长（秒）
    private int getTotalDurationByCourseId(Integer courseId) {
        // 获取课程的章节列表
        QueryWrapper<Chapter> chapterWrapper = new QueryWrapper<>();
        chapterWrapper.eq("course_id", courseId);
        List<Chapter> chapters = chapterMapper.selectList(chapterWrapper);
        
        if (chapters.isEmpty()) {
            return 0;
        }
        
        // 计算总时长
        int totalDuration = 0;
        for (Chapter chapter : chapters) {
            QueryWrapper<Lesson> lessonWrapper = new QueryWrapper<>();
            lessonWrapper.eq("chapter_id", chapter.getId());
            List<Lesson> lessons = lessonMapper.selectList(lessonWrapper);
            
            for (Lesson lesson : lessons) {
                totalDuration += (lesson.getDuration() != null ? lesson.getDuration() : 0);
            }
        }
        
        return totalDuration;
    }
    
    // 辅助方法：格式化时长
    private String formatDuration(int seconds) {
        int hours = seconds / 3600;
        int minutes = (seconds % 3600) / 60;
        
        if (hours > 0) {
            return hours + "h " + minutes + "m";
        } else {
            return minutes + "m";
        }
    }
    
    // 辅助方法：计算指定日期的观看时长（分钟）
    private int calculateWatchDurationByDate(Integer studentId, LocalDate date) {
        LocalDateTime startOfDay = date.atStartOfDay();
        LocalDateTime endOfDay = date.plusDays(1).atStartOfDay();
        
        // 获取当天的观看记录
        QueryWrapper<LessonProgress> wrapper = new QueryWrapper<>();
        wrapper.eq("student_id", studentId)
               .ge("last_watch", startOfDay)
               .lt("last_watch", endOfDay);
        List<LessonProgress> progressList = lessonProgressMapper.selectList(wrapper);
        
        // 计算总观看时长（这里简化处理，实际上应该计算每个课时的观看时长）
        int totalMinutes = 0;
        for (LessonProgress progress : progressList) {
            // 假设每个课时的进度变化代表实际观看了相应比例的时间
            Lesson lesson = lessonMapper.selectById(progress.getLessonId());
            if (lesson != null && lesson.getDuration() != null) {
                float progressValue = progress.getProgress() != null ? progress.getProgress() : 0;
                totalMinutes += (int) (lesson.getDuration() * progressValue / 60); // 转换为分钟
            }
        }
        
        return totalMinutes;
    }
    
    // 辅助方法：统计指定日期更新的课时数目
    private int countUpdatedLessonsByDate(Integer studentId, LocalDate date) {
        LocalDateTime startOfDay = date.atStartOfDay();
        LocalDateTime endOfDay = date.plusDays(1).atStartOfDay();
        
        // 获取当天更新的观看记录
        QueryWrapper<LessonProgress> wrapper = new QueryWrapper<>();
        wrapper.eq("student_id", studentId)
               .ge("last_watch", startOfDay)
               .lt("last_watch", endOfDay);
        Long count = lessonProgressMapper.selectCount(wrapper);
        
        return count != null ? count.intValue() : 0;
    }
    
    // 辅助方法：生成当月的学习日历数据
    private List<Map<String, Object>> generateMonthlyCalendarData(Integer studentId) {
        List<Map<String, Object>> calendarData = new ArrayList<>();
        
        // 获取当月的第一天和最后一天
        LocalDate now = LocalDate.now();
        LocalDate firstDayOfMonth = LocalDate.of(now.getYear(), now.getMonth(), 1);
        LocalDate lastDayOfMonth = LocalDate.of(now.getYear(), now.getMonth(), now.lengthOfMonth());
        
        // 生成当月每一天的数据
        for (LocalDate date = firstDayOfMonth; !date.isAfter(lastDayOfMonth); date = date.plusDays(1)) {
            int updatedLessons = countUpdatedLessonsByDate(studentId, date);
            
            String category;
            if (updatedLessons <= 2) {
                category = "light";
            } else if (updatedLessons <= 5) {
                category = "medium";
            } else {
                category = "heavy";
            }
            
            Map<String, Object> dayData = new HashMap<>();
            dayData.put("date", date.getDayOfMonth());
            dayData.put("hasActivity", updatedLessons > 0);
            dayData.put("activityLevel", category);
            dayData.put("isCurrent", date.equals(now));
            dayData.put("isCurrentMonth", true);
            
            calendarData.add(dayData);
        }
        
        // 填充日历前面的上月日期
        int firstDayOfWeek = firstDayOfMonth.getDayOfWeek().getValue() % 7; // 调整为周日为0
        for (int i = 0; i < firstDayOfWeek; i++) {
            LocalDate prevDate = firstDayOfMonth.minusDays(i + 1);
            
            Map<String, Object> dayData = new HashMap<>();
            dayData.put("date", prevDate.getDayOfMonth());
            dayData.put("hasActivity", false);
            dayData.put("isCurrentMonth", false);
            dayData.put("isCurrent", false);
            
            calendarData.add(0, dayData); // 添加到开头
        }
        
        // 填充日历后面的下月日期
        int remainingDays = 42 - calendarData.size(); // 6行7列的日历
        for (int i = 1; i <= remainingDays; i++) {
            LocalDate nextDate = lastDayOfMonth.plusDays(i);
            
            Map<String, Object> dayData = new HashMap<>();
            dayData.put("date", nextDate.getDayOfMonth());
            dayData.put("hasActivity", false);
            dayData.put("isCurrentMonth", false);
            dayData.put("isCurrent", false);
            
            calendarData.add(dayData); // 添加到结尾
        }
        
        return calendarData;
    }
    
    // 辅助方法：检查学生是否已订阅课程
    private boolean isStudentSubscribedCourse(Integer studentId, Integer courseId) {
        QueryWrapper<CourseSubscribe> wrapper = new QueryWrapper<>();
        wrapper.eq("student_id", studentId).eq("course_id", courseId);
        Long count = courseSubscribeMapper.selectCount(wrapper);
        return count != null && count > 0;
    }
} 